#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Inline Gettext
~~~~~~~~~~~~~~

An example extension for Jinja2 that supports inline gettext calls.
Requires the i18n extension to be loaded.

:copyright: (c) 2009 by the Jinja Team.
:license: BSD.
"""

import re
from ambari_jinja2.ext import Extension
from ambari_jinja2.lexer import Token, count_newlines
from ambari_jinja2.exceptions import TemplateSyntaxError


_outside_re = re.compile(r"\\?(gettext|_)\(")
_inside_re = re.compile(r"\\?[()]")


class InlineGettext(Extension):
  """This extension implements support for inline gettext blocks::

      <h1>_(Welcome)</h1>
      <p>_(This is a paragraph)</p>

  Requires the i18n extension to be loaded and configured.
  """

  def filter_stream(self, stream):
    paren_stack = 0

    for token in stream:
      if token.type is not "data":
        yield token
        continue

      pos = 0
      lineno = token.lineno

      while 1:
        if not paren_stack:
          match = _outside_re.search(token.value, pos)
        else:
          match = _inside_re.search(token.value, pos)
        if match is None:
          break
        new_pos = match.start()
        if new_pos > pos:
          preval = token.value[pos:new_pos]
          yield Token(lineno, "data", preval)
          lineno += count_newlines(preval)
        gtok = match.group()
        if gtok[0] == "\\":
          yield Token(lineno, "data", gtok[1:])
        elif not paren_stack:
          yield Token(lineno, "block_begin", None)
          yield Token(lineno, "name", "trans")
          yield Token(lineno, "block_end", None)
          paren_stack = 1
        else:
          if gtok == "(" or paren_stack > 1:
            yield Token(lineno, "data", gtok)
          paren_stack += gtok == ")" and -1 or 1
          if not paren_stack:
            yield Token(lineno, "block_begin", None)
            yield Token(lineno, "name", "endtrans")
            yield Token(lineno, "block_end", None)
        pos = match.end()

      if pos < len(token.value):
        yield Token(lineno, "data", token.value[pos:])

    if paren_stack:
      raise TemplateSyntaxError(
        "unclosed gettext expression", token.lineno, stream.name, stream.filename
      )
